using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Data;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using ALib;

namespace TradingPlatform
{
    public partial class TradingProgressBar : UserControl
    {
        private string _tradingPlatformTradingSessiontString;

        public TradingProgressBar()
        {
            InitializeComponent();

            Paint += new PaintEventHandler(TradingProgressBar_Paint);
        }

        public void Config(string symbol, int tradingPlatformTimeZoneIndex, int exchangeTimeZoneIndex, string exchangeTradingSessionString, int refreshTimeInterval)
        {
            labelSymbol.Text = symbol;
            UtcConverter utcConverter = new UtcConverter(tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex);

            _tradingPlatformTradingSessiontString = ConvertTradingSessionString_TradingPlatformToExchange(exchangeTradingSessionString, utcConverter);

            timerRefresh.Interval = refreshTimeInterval;
            timerRefresh.Enabled = true;
        }

        private static Dictionary<int, int> GetMarketOpenSections(int barLength, string tradingSessionString)
        {
            tradingSessionString = tradingSessionString ?? string.Empty;

            Dictionary<int, int> result = new Dictionary<int, int>();
            string[] times = tradingSessionString.Split(new char[] { '&', '-' });
            GoodValue.Assert(times.Length > 0 && times.Length % 2 == 0);
            List<int> points = new List<int>();
            for (int i = 0; i < times.Length; i++)
            {
                int x = GetTimeX(barLength, times[i]);
                points.Add(x);
            }

            for (int i = 0; i < times.Length / 2; i++)
            {
                int x0 = points[2 * i];
                int x1 = points[2 * i + 1];
                if (x0 != x1)
                {
                    if (x0 < x1)
                    {
                        result.Add(x0, x1);
                    }
                    else
                    {
                        result.Add(x0, barLength);
                        result.Add(0, x1);
                    }
                }
            }

            return result;
        }

        private static int GetTimeX(int barLength, string timeString)
        {
            string[] timeIterms = timeString.Split(new char[] { ':' });
            int hour = int.Parse(timeIterms[0]);
            int minute = int.Parse(timeIterms[1]);
            int second = int.Parse(timeIterms[2]);
            long dailyTicks = new TimeSpan(24, 0, 0).Ticks;
            long tempTicks = new TimeSpan(hour, minute, second).Ticks;
            Debug.Assert(tempTicks <= dailyTicks);
            int x = (int)(1.0 * tempTicks / dailyTicks * barLength);
            return x;
        }

        void TradingProgressBar_Paint(object sender, PaintEventArgs e)
        {
            Redraw();
        }


        private void Redraw()
        {
            Graphics g = CreateGraphics();

            if (timerRefresh.Enabled)
            {
                //g.Clear(SystemColors.AppWorkspace);

                Rectangle rect = new Rectangle(0, 0, Height, Height);

                LinearGradientBrush backgroundBrush = new LinearGradientBrush(rect, SystemColors.AppWorkspace, SystemColors.AppWorkspace, LinearGradientMode.Vertical);
                g.FillRectangle(backgroundBrush, 0, 0, Size.Width, Size.Height);

                LinearGradientBrush lgBrush = new LinearGradientBrush(rect, Color.Lime, Color.DarkGreen, LinearGradientMode.Vertical);

                Dictionary<int, int> marketOpenningSections = GetMarketOpenSections(this.Size.Width, _tradingPlatformTradingSessiontString);
                foreach (KeyValuePair<int, int> start_End in marketOpenningSections)
                {
                    //e.Graphics.FillRectangle(new SolidBrush(Color.Green), start_End.Key, 0, start_End.Value - start_End.Key, Size.Height);
                    g.FillRectangle(lgBrush, start_End.Key, 0, start_End.Value - start_End.Key, Size.Height);
                }

                // Display current time.
                int currentTimeX = GetTimeX(Size.Width, DateTime.Now.ToString("HH:mm:ss"));
                g.FillRectangle(new SolidBrush(Color.Gold), currentTimeX, 0, 2, Size.Height);
            }

        }

        private void timerReload_Tick(object sender, EventArgs e)
        {
            //Redraw();
        }

        private static string ConvertTradingSessionString_TradingPlatformToExchange(string exchangeTradingHours, UtcConverter utcConverter)
        {
            string[] times = exchangeTradingHours.Split(new char[] { '&', '-' });

            string tradingPlatformTradingHours = string.Empty;
            for (int i = 0; i < times.Length; i++)
            {
                TimeSpan exchangeTime = ALib.DateTimeConverter.ToTime(times[i]);
                DateTime exchangeDateTime = (DateTime.Now.Date + exchangeTime);
                string tradingPlatformTimeString = utcConverter.ExchangeTimeToTradingPlatformTime(exchangeDateTime).ToString("HH:mm:ss");
                if (i == 0)
                {
                    tradingPlatformTradingHours += tradingPlatformTimeString;
                }
                else
                {
                    if (i % 2 == 1)
                    {
                        tradingPlatformTradingHours += "-" + tradingPlatformTimeString;
                    }
                    else
                    {
                        tradingPlatformTradingHours += "&" + tradingPlatformTimeString;
                    }
                }
            }
            return tradingPlatformTradingHours;
        }

        private void TimeBarEx_Resize(object sender, EventArgs e)
        {
            if (_tradingPlatformTradingSessiontString != null)
            {
                Invalidate();
            }
        }
    }
}
